package com.flyduck.mall.oms.admin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyduck.mall.oms.admin.vo.*;
import com.flyduck.mall.oms.manager.PayManager;
import com.flyduck.mall.oms.mapper.OmsOrderMapper;
import com.flyduck.mall.oms.mapper.OmsRefundMapper;

import com.flyduck.mall.common.core.utils.BeanUtils;
import com.flyduck.ss.common.core.exception.ServiceException;
import com.flyduck.ss.common.core.utils.StringUtils;
import com.flyduck.mall.oms.api.constant.OrderConstant;
import com.flyduck.mall.oms.admin.service.AdminRefundService;

import com.flyduck.mall.oms.domain.OmsOrder;
import com.flyduck.mall.oms.domain.OmsOrderItem;
import com.flyduck.mall.oms.domain.OmsRefund;
import com.flyduck.mall.oms.mapper.OmsOrderItemMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * AdminRefundServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2024-06-13
 */
@Service
public class AdminRefundServiceImpl implements AdminRefundService {

    @Resource
    private OmsRefundMapper omsRefundMapper;
    @Resource
    private OmsOrderMapper omsOrderMapper;
    @Resource
    private PayManager payManager;
    @Resource
    private OmsOrderItemMapper omsOrderItemMapper;

    @Override
    public List<AdminDictRespVO> getRefundStatusList() {
        List<AdminDictRespVO> adminDictRespVOList = new ArrayList<>();
        for (OrderConstant.RefundStatus refundStatus : OrderConstant.RefundStatus.values()) {
            AdminDictRespVO adminDictRespVO = new AdminDictRespVO();
            adminDictRespVO.setKey(refundStatus.getCode());
            adminDictRespVO.setValue(refundStatus.getDescription());
            adminDictRespVOList.add(adminDictRespVO);
        }
        return adminDictRespVOList;
    }

    @Override
    public Page<AdminRefundRespVO> getRefundPage(Page page, AdminRefundQueryReqVO adminRefundQueryReqVO) {
        return omsRefundMapper.getRefundPage(page,adminRefundQueryReqVO);
    }

    @Override
    public AdminRefundDetailsRespVO getRefundDetailsById(Long id) {
        AdminRefundDetailsRespVO adminRefundDetailsRespVO = new AdminRefundDetailsRespVO();

        //退货
        OmsRefund omsRefund = omsRefundMapper.selectById(id);
        AdminRefundDetailsRespVO.OmsRefundVO appRefundVO = BeanUtils.toBean(omsRefund, AdminRefundDetailsRespVO.OmsRefundVO.class);
        adminRefundDetailsRespVO.setRefund(appRefundVO);

        //订单
        OmsOrder omsOrder = omsOrderMapper.selectById(omsRefund.getOrderId());
        List<OmsOrderItem> omsOrderItemList = omsOrderItemMapper.getAppOrderItemListByOrderId(omsOrder.getId());
        AdminRefundDetailsRespVO.OmsOrderVO appOrderVO = BeanUtils.toBean(omsOrder, AdminRefundDetailsRespVO.OmsOrderVO.class);
        List<AdminRefundDetailsRespVO.OmsOrderItemVO> appOrderItemVOList = BeanUtils.toBeanList(omsOrderItemList, AdminRefundDetailsRespVO.OmsOrderItemVO.class);
        appOrderVO.setOrderItems(appOrderItemVOList);
        adminRefundDetailsRespVO.setOrder(appOrderVO);

        return adminRefundDetailsRespVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditRefund(AdminRefundAuditReqVO adminRefundAuditReqVO) {
        OmsRefund omsRefund = omsRefundMapper.selectById(adminRefundAuditReqVO.getId());
        OmsOrder omsOrder = omsOrderMapper.selectById(omsRefund.getOrderId());

        if (OrderConstant.RefundStatus.PROCESSING.getCode() == adminRefundAuditReqVO.getRefundStatus() //退货中
                || OrderConstant.RefundStatus.REJECTED.getCode() == adminRefundAuditReqVO.getRefundStatus()) {//拒绝退货
            if(OrderConstant.RefundStatus.PENDING.getCode() != omsRefund.getRefundStatus()){
                throw new ServiceException("状态异常");
            }

            if(adminRefundAuditReqVO.getRefundAmount() == null || StringUtils.isBlank(adminRefundAuditReqVO.getOperateRemark())){
                throw new ServiceException("退款金额或处理备注不能为空");
            }

            if(adminRefundAuditReqVO.getRefundAmount().compareTo(omsOrder.getTotalAmount()) > 0){
                throw new ServiceException("退款金额不能大于订单总金额");
            }

            omsRefund.setRefundAmount(adminRefundAuditReqVO.getRefundAmount());
            omsRefund.setRefundStatus(adminRefundAuditReqVO.getRefundStatus());
            omsRefund.setOperateRemark(adminRefundAuditReqVO.getOperateRemark());
            omsRefund.setOperatorId(StpUtil.getLoginIdAsLong());
            omsRefund.setOperateTime(new Date());

            //如果是拒绝
            if(OrderConstant.RefundStatus.REJECTED.getCode() == adminRefundAuditReqVO.getRefundStatus()){
                omsOrder.setOrderStatus(OrderConstant.OrderStatus.REFUND_FAILED.getCode());
                omsOrderMapper.updateById(omsOrder);
            }

        }else if(OrderConstant.RefundStatus.COMPLETED.getCode() == adminRefundAuditReqVO.getRefundStatus()){//确认退货退款
            if(OrderConstant.RefundStatus.PROCESSING.getCode() != omsRefund.getRefundStatus()){//必须是退货中
                throw new ServiceException("状态异常");
            }

            if(StringUtils.isBlank(adminRefundAuditReqVO.getReceiptRemark())){
                throw new ServiceException("处理备注不能为空");
            }

            omsRefund.setReceiptRemark(adminRefundAuditReqVO.getReceiptRemark());
            omsRefund.setRefundStatus(adminRefundAuditReqVO.getRefundStatus());


            omsOrder.setOrderStatus(OrderConstant.OrderStatus.REFUNDED.getCode());
            omsOrder.setRefundTime(new Date());
            omsOrderMapper.updateById(omsOrder);

            //退款处理
            payManager.refund(omsRefund.getId());
        }
        omsRefund.setUpdateTime(new Date());
        omsRefundMapper.updateById(omsRefund);
    }
}
